package com.eshop.modules.activity.service.impl;

import java.lang.invoke.SerializedLambda;
import java.util.Comparator;
import java.util.function.Function;
import com.eshop.modules.product.service.dto.ProductResultDto;
import java.util.HashMap;
import com.eshop.modules.product.service.dto.ProductFormatDto;
import cn.hutool.core.collection.ListUtil;
import com.eshop.modules.product.service.dto.FromatDetailDto;
import com.eshop.enums.SpecTypeEnum;
import java.math.BigDecimal;
import cn.hutool.core.bean.BeanUtil;
import java.io.IOException;
import com.eshop.utils.FileUtil;
import java.util.ArrayList;
import javax.servlet.http.HttpServletResponse;
import com.eshop.common.utils.QueryHelpPlus;
import java.util.Iterator;
import java.util.LinkedHashMap;
import com.eshop.utils.OrderUtil;
import com.eshop.modules.activity.service.dto.StoreSeckillDto;
import com.github.pagehelper.PageInfo;
import org.springframework.data.domain.Pageable;
import com.eshop.modules.activity.service.dto.StoreSeckillQueryCriteria;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eshop.modules.activity.vo.StoreSeckillQueryVo;
import com.eshop.modules.product.domain.StoreProductAttrValue;
import java.util.Map;
import com.eshop.modules.product.vo.StoreProductAttrQueryVo;
import java.util.List;
import com.eshop.exception.BadRequestException;
import cn.hutool.core.util.ObjectUtil;
import java.io.Serializable;
import com.eshop.modules.template.domain.ShippingTemplates;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.eshop.utils.RedisUtil;
import com.eshop.api.EshopException;
import com.eshop.enums.ShopCommonEnum;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import java.util.Date;
import com.eshop.modules.activity.vo.StoreSeckillVo;
import com.eshop.modules.template.service.ShippingTemplatesService;
import com.eshop.modules.product.service.StoreProductAttrService;
import com.eshop.modules.product.service.StoreProductReplyService;
import org.springframework.beans.factory.annotation.Autowired;
import com.eshop.dozer.service.IGenerator;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Service;
import com.eshop.modules.activity.service.StoreSeckillService;
import com.eshop.modules.activity.domain.StoreSeckill;
import com.eshop.modules.activity.service.mapper.StoreSeckillMapper;
import com.eshop.common.service.impl.BaseServiceImpl;

@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = { Exception.class })
public class StoreSeckillServiceImpl extends BaseServiceImpl<StoreSeckillMapper, StoreSeckill> implements StoreSeckillService
{
    @Autowired
    private IGenerator generator;
    @Autowired
    private StoreSeckillMapper storeSeckillMapper;
    @Autowired
    private StoreProductReplyService replyService;
    @Autowired
    private StoreProductAttrService storeProductAttrService;
    @Autowired
    private ShippingTemplatesService shippingTemplatesService;
    
    public StoreSeckillVo getDetail(final Long id) {
        final Date now = new Date();
        final StoreSeckill storeSeckill = (StoreSeckill)(((((this.lambdaQuery().eq(StoreSeckill::getId, id)).eq(StoreSeckill::getStatus, ShopCommonEnum.IS_STATUS_1.getValue())).eq(StoreSeckill::getIsShow, ShopCommonEnum.SHOW_1.getValue())).le(StoreSeckill::getStartTime, now)).ge(StoreSeckill::getStopTime, now)).one();
        if (storeSeckill == null) {
            throw new EshopException("秒杀产品不存在或已下架");
        }
        final Map<String, Object> returnMap = this.storeProductAttrService.getProductAttrDetail(storeSeckill.getProductId());
        final String storeFreePostage = (String)RedisUtil.get("store_free_postage");
        String tempName = "";
        if (StrUtil.isBlank((CharSequence)storeFreePostage) || !NumberUtil.isNumber((CharSequence)storeFreePostage) || Integer.valueOf(storeFreePostage) == 0) {
            tempName = "全国包邮";
        }
        else {
            final ShippingTemplates shippingTemplates = (ShippingTemplates)this.shippingTemplatesService.getById((Serializable)storeSeckill.getTempId());
            if (!ObjectUtil.isNotNull(shippingTemplates)) {
                throw new BadRequestException("请配置运费模板");
            }
            tempName = shippingTemplates.getName();
        }
        return StoreSeckillVo.builder().productAttr((List<StoreProductAttrQueryVo>) returnMap.get("productAttr")).productValue((Map<String, StoreProductAttrValue>) returnMap.get("productValue")).storeInfo((StoreSeckillQueryVo)this.generator.convert(storeSeckill, (Class)StoreSeckillQueryVo.class)).reply(this.replyService.getReply(storeSeckill.getProductId())).replyCount(this.replyService.productReplyCount(storeSeckill.getProductId())).tempName(tempName).build();
    }
    
    public List<StoreSeckillQueryVo> getList(final int page, final int limit, final int time) {
        final Date nowTime = new Date();
        final Page<StoreSeckill> pageModel = (Page<StoreSeckill>)new Page((long)page, (long)limit);
        final LambdaQueryWrapper<StoreSeckill> wrapper = (LambdaQueryWrapper<StoreSeckill>)new LambdaQueryWrapper();
        ((((wrapper.eq(StoreSeckill::getStatus, ShopCommonEnum.IS_STATUS_1.getValue())).eq(StoreSeckill::getTimeId, time)).le(StoreSeckill::getStartTime, nowTime)).ge(StoreSeckill::getStopTime, nowTime)).orderByDesc(StoreSeckill::getSort);
        final List<StoreSeckillQueryVo> storeSeckillQueryVos = (List<StoreSeckillQueryVo>)this.generator.convert(((Page)this.storeSeckillMapper.selectPage((IPage)pageModel, (Wrapper)wrapper)).getRecords(), (Class)StoreSeckillQueryVo.class);
        storeSeckillQueryVos.forEach(item -> {
            Integer sum = item.getSales() + item.getStock();
            item.setPercent(NumberUtil.round(NumberUtil.mul((Number)NumberUtil.div((Number)item.getSales(), (Number)sum), (Number)100), 0).intValue());
            return;
        });
        return storeSeckillQueryVos;
    }
    
    public List<StoreSeckillQueryVo> getList(final int page, final int limit) {
        final Date nowTime = new Date();
        final Page<StoreSeckill> pageModel = (Page<StoreSeckill>)new Page((long)page, (long)limit);
        final LambdaQueryWrapper<StoreSeckill> wrapper = (LambdaQueryWrapper<StoreSeckill>)new LambdaQueryWrapper();
        ((((wrapper.eq(StoreSeckill::getStatus, ShopCommonEnum.IS_STATUS_1.getValue())).eq(StoreSeckill::getIsHot, 1)).le(StoreSeckill::getStartTime, nowTime)).ge(StoreSeckill::getStopTime, nowTime)).orderByDesc(StoreSeckill::getSort);
        final List<StoreSeckillQueryVo> storeSeckillQueryVos = (List<StoreSeckillQueryVo>)this.generator.convert(((Page)this.storeSeckillMapper.selectPage((IPage)pageModel, (Wrapper)wrapper)).getRecords(), (Class)StoreSeckillQueryVo.class);
        storeSeckillQueryVos.forEach(item -> {
            Integer sum = item.getSales() + item.getStock();
            item.setPercent(NumberUtil.round(NumberUtil.mul((Number)NumberUtil.div((Number)item.getSales(), (Number)sum), (Number)100), 0).intValue());
            return;
        });
        return storeSeckillQueryVos;
    }
    
    public Map<String, Object> queryAll(final StoreSeckillQueryCriteria criteria, final Pageable pageable) {
        this.getPage(pageable);
        final PageInfo<StoreSeckill> page = (PageInfo<StoreSeckill>)new PageInfo((List)this.queryAll(criteria));
        final List<StoreSeckillDto> storeSeckillDTOS = (List<StoreSeckillDto>)this.generator.convert(page.getList(), (Class)StoreSeckillDto.class);
        for (final StoreSeckillDto storeSeckillDTO : storeSeckillDTOS) {
            final String statusStr = OrderUtil.checkActivityStatus(storeSeckillDTO.getStartTime(), storeSeckillDTO.getStopTime(), storeSeckillDTO.getStatus());
            storeSeckillDTO.setStatusStr(statusStr);
        }
        final Map<String, Object> map = new LinkedHashMap<String, Object>(2);
        map.put("content", storeSeckillDTOS);
        map.put("totalElements", page.getTotal());
        return map;
    }
    
    public List<StoreSeckill> queryAll(final StoreSeckillQueryCriteria criteria) {
        return (List<StoreSeckill>)((StoreSeckillMapper)this.baseMapper).selectList((Wrapper)QueryHelpPlus.getPredicate(StoreSeckill.class, criteria));
    }
    
    public void download(final List<StoreSeckillDto> all, final HttpServletResponse response) throws IOException {
        final List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (final StoreSeckillDto yxStoreSeckill : all) {
            final Map<String, Object> map = new LinkedHashMap<String, Object>();
            map.put("推荐图", yxStoreSeckill.getImage());
            map.put("轮播图", yxStoreSeckill.getImages());
            map.put("活动标题", yxStoreSeckill.getTitle());
            map.put("简介", yxStoreSeckill.getInfo());
            map.put("返多少积分", yxStoreSeckill.getGiveIntegral());
            map.put("排序", yxStoreSeckill.getSort());
            map.put("库存", yxStoreSeckill.getStock());
            map.put("销量", yxStoreSeckill.getSales());
            map.put("单位名", yxStoreSeckill.getUnitName());
            map.put("邮费", yxStoreSeckill.getPostage());
            map.put("内容", yxStoreSeckill.getDescription());
            map.put("开始时间", yxStoreSeckill.getStartTime());
            map.put("结束时间", yxStoreSeckill.getStopTime());
            map.put("产品状态", yxStoreSeckill.getStatus());
            map.put("是否包邮", yxStoreSeckill.getIsPostage());
            map.put("热门推荐", yxStoreSeckill.getIsHot());
            map.put("最多秒杀几个", yxStoreSeckill.getNum());
            map.put("显示", yxStoreSeckill.getIsShow());
            map.put("时间段id", yxStoreSeckill.getTimeId());
            list.add(map);
        }
        FileUtil.downloadExcel((List)list, response);
    }
    
    public boolean saveSeckill(final StoreSeckillDto resources) {
        final ProductResultDto resultDTO = this.computedProduct(resources.getAttrs());
        final StoreSeckill storeSeckill = new StoreSeckill();
        BeanUtil.copyProperties(resources, storeSeckill, new String[] { "images" });
        if (resources.getImages().isEmpty()) {
            throw new EshopException("请上传轮播图");
        }
        storeSeckill.setStock(resultDTO.getStock());
        storeSeckill.setOtPrice(BigDecimal.valueOf(resultDTO.getMinOtPrice()));
        storeSeckill.setPrice(BigDecimal.valueOf(resultDTO.getMinPrice()));
        storeSeckill.setCost(BigDecimal.valueOf(resultDTO.getMinCost()));
        storeSeckill.setStock(resultDTO.getStock());
        storeSeckill.setImages(String.join(",", resources.getImages()));
        this.saveOrUpdate(storeSeckill);
        if (SpecTypeEnum.TYPE_0.getValue().equals(resources.getSpecType())) {
            final FromatDetailDto fromatDetailDto = FromatDetailDto.builder().value("规格").detailValue("").attrHidden("").detail(ListUtil.toList(new String[] { "默认" })).build();
            final List<ProductFormatDto> attrs = resources.getAttrs();
            final ProductFormatDto productFormatDto = attrs.get(0);
            productFormatDto.setValue1("规格");
            final Map<String, String> map = new HashMap<String, String>();
            map.put("规格", "默认");
            productFormatDto.setDetail(map);
            this.storeProductAttrService.insertYxStoreProductAttr(ListUtil.toList(new FromatDetailDto[] { fromatDetailDto }), ListUtil.toList(new ProductFormatDto[] { productFormatDto }), resources.getProductId());
        }
        else {
            this.storeProductAttrService.insertYxStoreProductAttr(resources.getItems(), resources.getAttrs(), resources.getProductId());
        }
        return true;
    }
    
    private ProductResultDto computedProduct(final List<ProductFormatDto> attrs) {
        final Double minPrice = attrs.stream().map(ProductFormatDto::getSeckillPrice).min(Comparator.naturalOrder()).orElse(0.0);
        final Double minOtPrice = attrs.stream().map(ProductFormatDto::getOtPrice).min(Comparator.naturalOrder()).orElse(0.0);
        final Double minCost = attrs.stream().map(ProductFormatDto::getCost).min(Comparator.naturalOrder()).orElse(0.0);
        final Integer stock = attrs.stream().map(ProductFormatDto::getSeckillStock).reduce(Integer::sum).orElse(0);
        if (stock <= 0) {
            throw new EshopException("库存不能低于0");
        }
        return ProductResultDto.builder().minPrice(minPrice).minOtPrice(minOtPrice).minCost(minCost).stock(stock).build();
    }
}
